package com.wanfajie.smsdistribute.ui.send_sms_bulk

import android.Manifest
import android.app.Activity
import android.app.AlertDialog
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.graphics.drawable.Drawable
import android.os.Build
import android.os.Bundle
import android.support.v7.widget.LinearLayoutManager
import android.support.v7.widget.RecyclerView
import android.util.Log
import android.view.*
import android.widget.PopupMenu
import android.widget.TextView
import com.wanfajie.smsdistribute.R
import com.wanfajie.smsdistribute.common.activity.BaseActivity
import com.wanfajie.smsdistribute.common.adapter.RecyclerViewHolder
import com.wanfajie.smsdistribute.db.bean.phone.PhoneGroup
import com.wanfajie.smsdistribute.db.bean.phone.PhoneNumber
import com.wanfajie.smsdistribute.db.repository.impl.GroupRepositoryImpl
import com.wanfajie.smsdistribute.receiver.sms.SmsSentStatusReceiver
import com.wanfajie.smsdistribute.template.SmsTemplate
import com.wanfajie.smsdistribute.template.convert.impl.TemplateSpannableConverter
import com.wanfajie.smsdistribute.db.bean.template.TemplateBean
import com.wanfajie.smsdistribute.ui.template_editor.PlaceholderSpan
import com.wanfajie.smsdistribute.ui.template_picker.TemplatePickerActivity
import com.wanfajie.smsdistribute.util.SimCardInfo
import com.wanfajie.smsdistribute.util.getSimInfoList
import com.wanfajie.smsdistribute.util.selectCard
import com.wanfajie.smsdistribute.util.toast
import kotlinx.android.synthetic.main.activity_send_sms_in_bulk.*
import java.util.*

class SendSmsBulkActivity : BaseActivity() {

    companion object {
        private const val EXTRA_KEY_TEMPLATE = "template"
        private const val EXTRA_KEY_TEMPLATE_ID = "template_id"
        private const val EXTRA_KEY_TEMPLATE_NAME = "template_name"

        private const val TEMPLATE_REQUEST_CODE = 1
        private const val TAG = "SendSmsBulkActivity"

        fun startActivity(ctx: Context, bean: TemplateBean) {
            val intent = Intent(ctx, SendSmsBulkActivity::class.java)
            val template = SmsTemplate.Builder(bean).create()

            intent.putExtra(EXTRA_KEY_TEMPLATE, template)
            intent.putExtra(EXTRA_KEY_TEMPLATE_ID, bean.id)
            intent.putExtra(EXTRA_KEY_TEMPLATE_NAME, bean.title)
            ctx.startActivity(intent)
        }

        @JvmStatic
        private val DOWN_UP_ICON_ID = arrayOf(R.drawable.ic_keyboard_arrow_down_gray_24dp,
                R.drawable.ic_keyboard_arrow_up_gray_24dp)
    }

    override val requiredPermissions: Array<String>? = arrayOf(Manifest.permission.SEND_SMS)

    private val groupList by lazy {
        GroupRepositoryImpl.getGroups()
    }

    private val mGroupMenuMap: MutableMap<MenuItem, PhoneGroup> = WeakHashMap<MenuItem, PhoneGroup>()

    private lateinit var mArrowIcon: List<Drawable>
    private var isSmsPreviewOpen = false

    private var mFormChanged = false
    private var mSelectedGroup: PhoneGroup? = null
        set(v) {
            field = v
            mFormChanged = true
            if (isSmsPreviewOpen) {
                mAdapter.notifyDataSetChanged()
            }
        }
    private var mSelectedTemplate: SmsTemplate? = null
        set(v) {
            field = v
            mFormChanged = true
            if (isSmsPreviewOpen) {
                mAdapter.notifyDataSetChanged()
            }
        }
    private var mSelectedGroupItems: List<PhoneNumber>? = null

    private var mSelectedCardIndex: Int = -1
    private val mSpanConverter by lazy {
        TemplateSpannableConverter {
            object : PlaceholderSpan(
                    bgColor = resources.getColor(R.color.colorPrimaryDark),
                    textColor = Color.WHITE
            ) {
                override fun onSpanClick(view: View, span: PlaceholderSpan, text: String, pos: Int) {
                    // TODO: 统计多少缺失
                }
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_send_sms_in_bulk)
        setSupportActionBar(toolbar)

        supportActionBar?.setDisplayHomeAsUpEnabled(true)
        supportActionBar?.setTitle(R.string.send_in_bulk)
        mArrowIcon = DOWN_UP_ICON_ID.map {
            resources.getDrawable(it).apply {
                setBounds(0, 0, minimumWidth, minimumHeight)
            }
        }
        sms_preview.layoutManager = LinearLayoutManager(this)
        sms_preview.adapter = mAdapter

        val simCardList = getSimInfoList()
        println(simCardList)
        btn_select_phone.setOnClickListener {
            selectCard(this, btn_select_phone) { info ->
                setCard(info)
            }
        }
        if (simCardList.isNotEmpty())
            setCard(simCardList[0])

        parseIntent()

        btn_select_group.setOnClickListener {
            val popupMenu = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                PopupMenu(this, it, Gravity.END or Gravity.TOP)
            } else {
                PopupMenu(this, it)
            }

            popupMenu.setOnMenuItemClickListener { item ->
                val selected = mGroupMenuMap[item]
                val count = selected!!.phoneNumbers?.size ?: 0
                if (count == 0) {
                    toast("分组为空")
                    return@setOnMenuItemClickListener false
                }

                mSelectedGroup = selected
                mSelectedGroupItems = mSelectedGroup!!.phoneNumbers?.toList() ?: emptyList()
                val title = mSelectedGroup!!.groupName
                btn_select_group.text = title + " " + getString(R.string.specific_item_count, count)
                true
            }
            renderGroupMenuItem(popupMenu.menu)
            popupMenu.show()
        }

        btn_select_template.setOnClickListener {
            val intent = Intent(this, TemplatePickerActivity::class.java)
            startActivityForResult(intent, TEMPLATE_REQUEST_CODE)
        }

        btn_show_sms_preview.setOnClickListener {
            toggleSmsPreview()
        }

    }

    private fun checkValidate(): Boolean = when {
        mSelectedGroup == null -> {
            toast(strId = R.string.please_select_a_group)
            false
        }
        mSelectedTemplate == null -> {
            toast(strId = R.string.please_select_a_template)
            false
        }
        mSelectedCardIndex == -1 -> {
            AlertDialog.Builder(this)
                    .setTitle(R.string.no_phone_card_available)
                    .setMessage(R.string.no_phone_card_detail)
                    .setPositiveButton(R.string.ok, null)
                    .show()
            false
        }
        else -> true
    }

    private val mAdapter by lazy {
        object : RecyclerView.Adapter<RecyclerViewHolder>() {
            private val inflater : LayoutInflater = LayoutInflater.from(this@SendSmsBulkActivity)

            override fun onCreateViewHolder(p0: ViewGroup, p1: Int): RecyclerViewHolder {
                val view = inflater.inflate(R.layout.list_item_sms_preview, p0, false)
                return RecyclerViewHolder(view)
            }

            override fun getItemCount(): Int {
                return mSelectedGroup?.phoneNumbers?.size ?: 0
            }

            override fun onBindViewHolder(p0: RecyclerViewHolder, p1: Int) {
                val phone = mSelectedGroupItems!![p1]
                p0.get<TextView>(R.id.name).text = phone.name
                p0.get<TextView>(R.id.number).text = phone.getNumber()
                p0.get<TextView>(R.id.content).text = mMessages[phone]
            }
        }
    }

    private fun renderAndSendSms() {
        if (!checkValidate()) return

        var count = 0
        mSelectedGroup!!.phoneNumbers?.forEach {
            val msg = mSelectedTemplate!!.render(it)
                SmsSentStatusReceiver.sendSmsMessage(
                        this@SendSmsBulkActivity, it.getNumber(),
                        msg, mSelectedCardIndex)
            count++
        }

        finish()
        toast(getString(R.string.sent_count_result, count))
    }

    private var mMsgCache: Map<PhoneNumber, String> = emptyMap()
    private val mMessages: Map<PhoneNumber, String> get() {
        if (mFormChanged && mSelectedTemplate != null && mSelectedGroup != null) {
            val newMap = mSelectedGroup!!.phoneNumbers?.map {
                it to mSelectedTemplate!!.render(it)
            }?.toMap()

            if (newMap != null)
                mMsgCache = newMap
        }

        mFormChanged = false
        return mMsgCache
    }

    private fun toggleSmsPreview() {
        isSmsPreviewOpen = !isSmsPreviewOpen

        val drawable: Drawable
        if (isSmsPreviewOpen) {
            sms_preview.visibility = View.VISIBLE
            drawable = mArrowIcon[1]
            mAdapter.notifyDataSetChanged()
        } else {
            sms_preview.visibility = View.GONE
            drawable = mArrowIcon[0]
        }

        btn_show_sms_preview.setCompoundDrawables(null, null, drawable, null)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (resultCode != Activity.RESULT_OK) return

        when (requestCode) {
            TEMPLATE_REQUEST_CODE -> {
                data?.getParcelableExtra<SmsTemplate>(
                        TemplatePickerActivity.EXTRA_KEY_TEMPLATE)?.let {

                    val name = data.getStringExtra(TemplatePickerActivity.EXTRA_KEY_TEMPLATE_NAME)
                    setTemplate(name, it)
                }
            }
            else -> Log.w(TAG, "未知来源Result: $requestCode $data")
        }
    }

    private fun setTemplate(name: String, template: SmsTemplate) {
        mSelectedTemplate = template
        btn_select_template.text = name
        template_preview.setText(mSelectedTemplate!!.convert(mSpanConverter))
    }

    private fun renderGroupMenuItem(menu: Menu) {
        groupList.forEach {
            val item = menu.add(it.groupName)
            mGroupMenuMap[item] = it
        }
    }

    private fun setCard(info: SimCardInfo) {
        mSelectedCardIndex = info.slotIndex
        btn_select_phone.text = getString(R.string.card_info,
                info.slotIndex+1, info.carrierName, info.number)
    }

    override fun onOptionsItemSelected(item: MenuItem?): Boolean {
        return when (item?.itemId) {
            android.R.id.home -> {
                finish()
                true
            }
            R.id.send -> {
                renderAndSendSms()
                true
            }
            else -> super.onOptionsItemSelected(item)
        }
    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_send_sms, menu)
        return true
    }

    private fun parseIntent() {
        intent.getParcelableExtra<SmsTemplate>(EXTRA_KEY_TEMPLATE)?.let {
            val name = intent.getStringExtra(EXTRA_KEY_TEMPLATE_NAME)
            setTemplate(name, it)
        }
    }
}